#include "iot/thing.h"
#include "board.h"
#include "audio_codec.h"
#include <driver/gpio.h>
#include <driver/uart.h>
#include <esp_log.h>
#include <freertos/timers.h>

#define TAG "Uart"
// 串口配置
#define UART_PORT_NUM      UART_NUM_1
#define UART_TX_PIN        GPIO_NUM_10
#define UART_RX_PIN        GPIO_NUM_18
#define UART_BAUD_RATE     9600
#define UART_BUF_SIZE      1024

namespace iot {

class Uart : public Thing {
private:
    TimerHandle_t auto_stop_timer;  // 自动停止定时器
    
    // 初始化串口
    void InitializeUart() {
        uart_config_t uart_config = {
            .baud_rate = UART_BAUD_RATE,
            .data_bits = UART_DATA_8_BITS,
            .parity = UART_PARITY_DISABLE,
            .stop_bits = UART_STOP_BITS_1,
            .flow_ctrl = UART_HW_FLOWCTRL_DISABLE,
            .source_clk = UART_SCLK_APB,
        };
        
        // 安装UART驱动程序
        esp_err_t err = uart_driver_install(UART_PORT_NUM, UART_BUF_SIZE, UART_BUF_SIZE, 0, NULL, 0);
        if (err != ESP_OK) {
            ESP_LOGE(TAG, "UART驱动安装失败: %d", err);
            return;
        }
        
        err = uart_param_config(UART_PORT_NUM, &uart_config);
        if (err != ESP_OK) {
            ESP_LOGE(TAG, "UART参数配置失败: %d", err);
            return;
        }
        
        err = uart_set_pin(UART_PORT_NUM, UART_TX_PIN, UART_RX_PIN, UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE);
        if (err != ESP_OK) {
            ESP_LOGE(TAG, "UART引脚配置失败: %d", err);
            return;
        }
        
        ESP_LOGI(TAG, "UART%d初始化完成，波特率：%d", UART_PORT_NUM, UART_BAUD_RATE);
    }
    
    // 串口发送函数
    void SendUartCommand(const std::string& command) {
        int len = uart_write_bytes(UART_PORT_NUM, command.c_str(), command.length());
        if (len == command.length()) {
            ESP_LOGI(TAG, "串口指令发送成功: %s", command.c_str());
        } else {
            ESP_LOGE(TAG, "串口指令发送失败: %s (已发送 %d/%d 字节)", 
                    command.c_str(), len, command.length());
        }
    }

    // 发送指令并设置自动停止
    void SendCommandWithAutoStop(const std::string& prefix, const std::string& command) {
        // 取消之前的自动停止定时器
        if (xTimerIsTimerActive(auto_stop_timer)) {
            xTimerStop(auto_stop_timer, 0);
        }
        
        // 发送指令前缀
        SendUartCommand(prefix);
        // 发送实际指令
        SendUartCommand(command);
        ESP_LOGI(TAG, "已发送指令: %s%s", prefix.c_str(), command.c_str());
        
        // 启动新的自动停止定时器
        if (xTimerStart(auto_stop_timer, 0) != pdPASS) {
            ESP_LOGE(TAG, "自动停止定时器启动失败");
        }
    }

    // 定时器回调函数
    static void AutoStopCallback(TimerHandle_t xTimer) {
        Uart* uart_instance = (Uart*)pvTimerGetTimerID(xTimer);
        uart_instance->SendUartCommand("K");
        uart_instance->SendUartCommand("Z");
        ESP_LOGI(TAG, "已发送自动停止指令: Z");
    }

public:
    Uart() : Thing("Uart", "串口指令控制器") {
        // 创建单次定时器（2000毫秒后触发）
        auto_stop_timer = xTimerCreate(
            "AutoStopTimer",              // 定时器名称
            pdMS_TO_TICKS(2000),          // 2000毫秒
            pdFALSE,                      // 单次模式
            (void*)this,                  // 传递this指针作为ID
            AutoStopCallback              // 回调函数
        );
        
        if (auto_stop_timer == NULL) {
            ESP_LOGE(TAG, "自动停止定时器创建失败");
        }
        
        InitializeUart();
        
        // 统一指令处理函数
        auto add_auto_stop_method = [this](const char* name, const char* desc, 
                                          const std::string& prefix, const std::string& cmd) {
            methods_.AddMethod(name, desc, ParameterList(),
                [this, prefix, cmd](const ParameterList&) {
                    SendCommandWithAutoStop(prefix, cmd);
                });
        };
        
        // 添加所有需要自动停止的指令，指定正确的前缀
        // 前进、后退、左转、右转、加速、减速使用"K"前缀
        add_auto_stop_method("go_forward", "前进指令", "K", "A");
        add_auto_stop_method("turn_right", "右转指令", "K", "C");
        add_auto_stop_method("turn_left", "左转指令", "K", "G");
        add_auto_stop_method("back_up", "后退指令", "K", "E");
        add_auto_stop_method("speed_cut", "减速指令", "K", "Y");
        add_auto_stop_method("speed_up", "加速指令", "K", "X");
        
        // 斜方向指令使用"J"前缀
        add_auto_stop_method("upper_right", "右上指令", "J", "B");
        add_auto_stop_method("low_right", "右下指令", "J", "D");
        add_auto_stop_method("up_left", "左上指令", "J", "H");
        add_auto_stop_method("low_left", "左下指令", "J", "F");
        
        // 停止指令（特殊处理，不触发自动停止）
        methods_.AddMethod("stop", "停止指令", ParameterList(),
            [this](const ParameterList&) {
                // 取消自动停止定时器
                if (xTimerIsTimerActive(auto_stop_timer)) {
                    xTimerStop(auto_stop_timer, 0);
                }
                SendUartCommand("K"); 
                SendUartCommand("Z"); 
                ESP_LOGI(TAG, "已发送停止指令: Z");
            });
            
    }

    ~Uart() {
        // 销毁定时器
        if (auto_stop_timer != NULL) {
            xTimerDelete(auto_stop_timer, 0);
        }
    }
};

} // namespace iot

DECLARE_THING(Uart);